package org.dgt.service.api.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dgt.dao.PersistenceManagerHibernate;
import org.dgt.model.core.Image;
import org.dgt.model.core.Product;
import org.dgt.model.core.ProductPriceUserRegistry;
import org.dgt.model.core.UserInformation;
import org.dgt.service.api.ProductService;
import org.dgt.web.model.ProductModel;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

public class ProductServiceImpl implements ProductService {

	private PersistenceManagerHibernate persistenceManager;
	
	//getter for prersistenceManager
	public void setPersistenceManager(PersistenceManagerHibernate persistenceManager) {
		this.persistenceManager = persistenceManager;
	}

	public int getQuantityOfProduct(Long productId) {
		String query = "from ProductPriceUserRegistry p where p.product.id = :id and p.sellerOrBuyer = :seller";
		List<ProductPriceUserRegistry> productPriceUserRegistryToSell = 
				persistenceManager.findByNamedParam(ProductPriceUserRegistry.class, query, new String[]{"id", "seller"}, new Object[]{productId, true});
		int result = 0;
		for(ProductPriceUserRegistry p : productPriceUserRegistryToSell){
			result +=p.getQuantity();
		}
		return result;
	}

	public int getQuantityOfProductWithPrice(Long productId, float price) {
		String query = "from ProductPriceUserRegistry p where p.product.id = :id and p.sellerOrBuyer = :seller and p.priceRegistry = :price";
		List<ProductPriceUserRegistry> productPriceUserRegistryToSell = 
				persistenceManager.findByNamedParam(ProductPriceUserRegistry.class, 
						query, new String[]{"id", "seller", "price"}, new Object[]{productId, true, price});
		int result = 0;
		for(ProductPriceUserRegistry p : productPriceUserRegistryToSell){
			result +=p.getQuantity();
		}
		return result;
	}

	public List<UserInformation> getSellerWithPrice(Long productId, float price) {
		String query = "from ProductPriceUserRegistry p where p.product.id = :id and p.sellerOrBuyer = :seller";
		List<ProductPriceUserRegistry> productPriceUserRegistryToSell = 
				persistenceManager.findByNamedParam(ProductPriceUserRegistry.class, query, new String[]{"id", "seller"}, new Object[]{productId, true});
		List<UserInformation> result = new ArrayList<UserInformation>();
		for(ProductPriceUserRegistry p : productPriceUserRegistryToSell){
			result.add(p.getUserInfo());
		}
		return result;
	}

	public List<UserInformation> getBuyerWithPrice(Long productId, float price) {
		String query = "from ProductPriceUserRegistry p where p.product.id = :id and p.sellerOrBuyer = :seller";
		List<ProductPriceUserRegistry> productPriceUserRegistryToSell = 
				persistenceManager.findByNamedParam(ProductPriceUserRegistry.class, query, new String[]{"id", "seller"}, new Object[]{productId, false});
		List<UserInformation> result = new ArrayList<UserInformation>();
		for(ProductPriceUserRegistry p : productPriceUserRegistryToSell){
			result.add(p.getUserInfo());
		}
		return result;
	}

	public List<Image> getImages(Long productId) {
		Product p = persistenceManager.findById(Product.class, productId);
		return p.getImages();
	}

	public List<ProductModel> getAllProductWithMinPrice() {
		List<Product> products = persistenceManager.findAll(Product.class);
		List<ProductModel> models = new ArrayList<ProductModel>();
		for(Product product : products){
			ProductModel model = getProductWithMinPrice(product.getId());
			models.add(model);
		}
		return models;
	}

	@SuppressWarnings("unchecked")
	public ProductModel getProductWithMinPrice(final Long productId) {
		final ProductModel model = new ProductModel();
		final String queryString = "select p.product.id, p.product.name, sum(p.quantity), min(p.priceRegistry) " +
				"from ProductPriceUserRegistry p " +
				"where p.product.id = :id and p.sellerOrBuyer = :seller " +
				"group by p.product.id, p.product.name, p.priceRegistry " +
				"having sum(p.quantity) > 0 " +
				"order by p.priceRegistry";
		persistenceManager.getHibernateTemplate().execute(new HibernateCallback() {

			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(queryString);
				query.setLong("id", productId);
				query.setBoolean("seller", true);
				Iterator results = query.iterate();
				//we get the first record
				Object[] row = (Object[]) results.next();
				model.setId((Long) row[0]);
				model.setName((String) row[1]);
				model.setNumOfSell((Long)row[2]);
				model.setPrice((Float) row[3]);
				model.setNumOfBuy(0);
				model.setProperties("");
				return null;
			}
			
		});
		return model;
	}

}
